/******************************************************************************
 * FileName:    gwin_btn_task.c
 * Desc:        按键任务
 *
 *
 * Author:      Lin
 * Notes:
 *
 ******************************************************************************/

/*-------------------------- Includes ---------------------------------------*/
#include "gwin_btn_task.h"

#include "gwin_main_task.h"


/*-------------------------- Macro Definitions ------------------------------*/
#define LOCAL_DEBUG_EN                      ( 0 )
#if LOCAL_DEBUG_EN
#define GWIN_DEBUG(...)                     USER_DEBUG(__VA_ARGS__)
#else
#define GWIN_DEBUG(...)
#endif


#define BTN_SEND_EVENT_PRESS_DOWN(index)                // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_PRESS_DOWN)
#define BTN_SEND_EVENT_PRESS_UP(index)                  // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_PRESS_UP)
#define BTN_SEND_EVENT_CLICK_REPEAT(index)              // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_CLICK_REPEAT)
#define BTN_SEND_EVENT_SINGLE_CLICK(index)              gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_SINGLE_CLICK)
#define BTN_SEND_EVENT_DOUBLE_CLICK(index)              // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_DOUBLE_CLICK)
#define BTN_SEND_EVENT_LONG_PRESS_DOWN(index)           // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_LONG_PRESS_DOWN)
#define BTN_SEND_EVENT_LONG_PRESS_UP(index)             // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_LONG_PRESS_UP)
#define BTN_SEND_EVENT_LONG_PRESS_HOLD(index)           // gwin_main_btn_event(index, MAIN_TASK_MSG_BTN_SUBTYPE_LONG_PRESS_HOLD)


/*-------------------------- Type Declarations ------------------------------*/

/*-------------------------- Global Variables -------------------------------*/
static void *gwin_btn_task_timer = NULL;


/*-------------------------- Local Variables --------------------------------*/
static btn_ctrl_t btn_task_ctrl[BTN_CNT_MAX];


/*-------------------------- Functions Declarations -------------------------*/

/*-------------------------- Functions Definitions --------------------------*/
/**
 * @brief 按键 打开按键连续判断
 */
void gwin_btn_cfg_set_click_repeat_en(uint8_t index, uint8_t value)
{
    btn_task_ctrl[index].click_repeat_en = (value > 0);
}


/**
 * @brief 任务初始化
 */
void gwin_btn_task_init(void)
{
    memset(btn_task_ctrl, 0, sizeof(btn_task_ctrl));

    gwin_btn_task_timer = os_timer_create("gwin_btn_task", 10, TRUE, 0, gwin_btn_task);
    GWIN_OS_TIMER_ASSERT(gwin_btn_task_timer);
    os_timer_start(gwin_btn_task_timer, 0);
}

/**
 * @brief 任务
 */
void gwin_btn_task(void *param)
{
    for (uint8_t index = 0; index < BTN_CNT_MAX; index++)
    {
        uint8_t cur_state = gwin_btn_get_state(index);

        // 消抖
        if (cur_state != btn_task_ctrl[index].cur_state)
        {
            // 多次读到新电平，则认为有效
            if (++(btn_task_ctrl[index].debounce_cnt) >= DEBOUNCE_TIME_10MS)
            {
                btn_task_ctrl[index].cur_state = cur_state;
                btn_task_ctrl[index].debounce_cnt = 0;
            }
        }
        else
        {
            // 电平相同，清零消抖
            btn_task_ctrl[index].debounce_cnt = 0;
        }

        switch (btn_task_ctrl[index].ctrl_state)
        {
            // 首次按下
            case 0:
            {
                if (btn_task_ctrl[index].cur_state)
                {
                    // 按下事件
                    BTN_SEND_EVENT_PRESS_DOWN(index);
                    gwin_save_general_clock(&btn_task_ctrl[index].time_clock);
                    btn_task_ctrl[index].short_cnt = 1;
                    btn_task_ctrl[index].ctrl_state = 1;
                    btn_task_ctrl[index].trigger_long = 0;
                }
            }
            break;

            // 按下后判断松手
            case 1:
            {
                if (btn_task_ctrl[index].cur_state)
                {
                    // 长按
                    if (!btn_task_ctrl[index].trigger_long && gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_LONG))
                    {
                        btn_task_ctrl[index].trigger_long = 1;
                        if (btn_task_ctrl[index].click_repeat_en)
                        {
                            BTN_SEND_EVENT_LONG_PRESS_DOWN(index);
                        }
                    }
                    // 长按保持
                    else if (gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_LONG_HOLD))
                    {
                        BTN_SEND_EVENT_LONG_PRESS_HOLD(index);
                        btn_task_ctrl[index].ctrl_state = 4;
                    }
                }
                else
                {
                    // 短按松手
                    BTN_SEND_EVENT_PRESS_UP(index);
                    if (gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_LONG) && !gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_LONG_HOLD))
                    {
                        // 长按松手
                        if (!btn_task_ctrl[index].click_repeat_en)
                        {
                            BTN_SEND_EVENT_LONG_PRESS_UP(index);
                        }
                        gwin_clear_general_clock(&btn_task_ctrl[index].time_clock);
                        btn_task_ctrl[index].ctrl_state = 0;
                    }
                    else
                    {
//                        #if BTN_CLICK_REPEAT
//                        // 准备连按判断
//                        gwin_save_general_clock(&btn_task_ctrl[index].time_clock);
//                        btn_task_ctrl[index].ctrl_state = 2;
//                        #else
//                        BTN_SEND_EVENT_SINGLE_CLICK(index);
//                        btn_task_ctrl[index].ctrl_state = 0;
//                        #endif

                        if (btn_task_ctrl[index].click_repeat_en)
                        {
                            // 准备连按判断
                            gwin_save_general_clock(&btn_task_ctrl[index].time_clock);
                            btn_task_ctrl[index].ctrl_state = 2;
                        }
                        else
                        {
                            BTN_SEND_EVENT_SINGLE_CLICK(index);
                            btn_task_ctrl[index].ctrl_state = 0;
                        }
                    }
                }
            }
            break;

            // 连按判断
            case 2:
            {
                if (btn_task_ctrl[index].cur_state)
                {
                    BTN_SEND_EVENT_PRESS_DOWN(index);
                    btn_task_ctrl[index].short_cnt++;
                    BTN_SEND_EVENT_CLICK_REPEAT(index);
                    gwin_save_general_clock(&btn_task_ctrl[index].time_clock);
                    btn_task_ctrl[index].ctrl_state = 3;
                }
                else
                {
                    // 松手超时
                    if (gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_SHORT_RELEASE))
                    {
                        // 单击
                        if (btn_task_ctrl[index].short_cnt == 1)
                        {
                            BTN_SEND_EVENT_SINGLE_CLICK(index);
                        }
                        // 双击
                        else if (btn_task_ctrl[index].short_cnt == 2)
                        {
                            BTN_SEND_EVENT_DOUBLE_CLICK(index);
                        }
                        gwin_clear_general_clock(&btn_task_ctrl[index].time_clock);
                        btn_task_ctrl[index].ctrl_state = 0;
                    }
                }
            }
            break;

            // 连按判断
            case 3:
            {
                if (btn_task_ctrl[index].cur_state)
                {
                    // 连按中长按
                    if (gwin_pass_general_clock(btn_task_ctrl[index].time_clock, BTN_TIME_LONG))
                    {
                        btn_task_ctrl[index].short_cnt = 0;
                        btn_task_ctrl[index].ctrl_state = 1;
                    }
                }
                else
                {
                    BTN_SEND_EVENT_PRESS_UP(index);
                    gwin_save_general_clock(&btn_task_ctrl[index].time_clock);
                    btn_task_ctrl[index].ctrl_state = 2;
                }
            }
            break;

            // 长按保持
            case 4:
            {
                if (btn_task_ctrl[index].cur_state)
                {
//                    BTN_SEND_EVENT_LONG_PRESS_HOLD(index);
                }
                // 长按保持松手
                else
                {
                    BTN_SEND_EVENT_PRESS_UP(index);
                    gwin_clear_general_clock(&btn_task_ctrl[index].time_clock);
                    btn_task_ctrl[index].ctrl_state = 0;
                }
            }
            break;

            default:
            {
                gwin_clear_general_clock(&btn_task_ctrl[index].time_clock);
                btn_task_ctrl[index].ctrl_state = 0;
            }
            break;
        }
    }
}


/*-------------------------- END OF FILE ------------------------------------*/


